package controller;

import model.HUD;
import model.GUI;
import model.Stage;
import model.Water;

import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.World;
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;

public class Global {
	public static final float targetFPS = 60; // DON'T TOUCH
	public static float physicsStep = 1 / targetFPS;
	public static float maxZoom = 60;
	public static float minZoom = 1;
	public static float zoom = 1;
	public static float metersX = 16;
	public static float waterLevel = 10;
	public static float worldSize = 100;
	public static boolean fullscreen = true;

	public static Input input; // must be set from in game
	public static float metersY;
	public static float pixelsPerMeter;
	public static float halfMetersX, halfMetersY, halfScreenX, halfScreenY,
			ratioX, ratioY;
	public static int screenX, screenY, mouseX, mouseY;
	public static World world;
	public static Stage stage;
	public static AppGameContainer app;
	public static Body player; 
	public static Water water;
	public static HUD hud;
	public static GUI gui;
	
	public static void init() {

		try {
			app = new AppGameContainer(new Game());

			screenX = app.getScreenWidth();
			screenY = app.getScreenHeight();
			
			metersY = metersX * ((float) screenY / (float) screenX);
			pixelsPerMeter = screenX / metersX;
			halfMetersX = metersX / 2;
			halfMetersY = metersY / 2;
			halfScreenX = screenX / 2;
			halfScreenY = screenY / 2;
			ratioX = screenX / metersX;
			ratioY = screenY / metersY;

			app.setDisplayMode(screenX, screenY, Global.fullscreen);
			app.setTargetFrameRate((int) Global.targetFPS);
			app.setVSync(true);
			app.setShowFPS(true);
			app.start();

		} catch (SlickException e) {
			e.printStackTrace();
		}
	}

	public static void changeScale(float scale) {
		metersX += scale;
		if (metersX < minZoom) {
			metersX = minZoom;
		} else if (metersX > maxZoom) {
			metersX = maxZoom;
		}
		zoom = 16.0f / metersX;
		metersY = metersX * ((float) screenY / (float) screenX);
		pixelsPerMeter = screenX / metersX;
		precalc();
	}

	public static void setScale(float scale) {
		metersX = scale;
		zoom = 1.0f;
		metersY = metersX * ((float) screenY / (float) screenX);
		pixelsPerMeter = screenX / metersX;
		precalc();
	}

	public static void precalc() {
		halfMetersX = metersX / 2;
		halfMetersY = metersY / 2;
		halfScreenX = screenX / 2;
		halfScreenY = screenY / 2;
		ratioX = screenX / metersX;
		ratioY = screenY / metersY;
	}

	public static Vec2 screenToWorld(float mx, float my) {
		Vec2 p = player.getPosition();
		float modX = p.x + (mx / pixelsPerMeter) - halfMetersX;
		float modY = (metersY - (my / ratioY))
				+ ((p.y < halfMetersY) ? 0 : -halfMetersY + (p.y));
		return new Vec2(modX, modY);
	}

	public static Vec2 worldToScreen(float mx, float my) {
		Vec2 p = player.getPosition();
		float modX = (mx * pixelsPerMeter) - (p.x * pixelsPerMeter)
				+ halfScreenX;
		float modY = screenY - (my * pixelsPerMeter);
		if (p.y < halfMetersY) {
			modY += 0;
		} else {
			modY += -halfScreenY + (p.y * pixelsPerMeter);
		}
		return new Vec2(modX, modY);
	}
}